package main.java.DMDE.persistence;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import main.java.DMDE.model.*;
import main.java.DMDE.model.Visibility;
import main.java.common.IXmlManager;

public class MethodXmlManager implements IXmlManager<Method> {

	private ModifierXmlManager modifierManager = new ModifierXmlManager();
	private TypeXmlManager typeManager = new TypeXmlManager();
	private ParameterXmlManager parameterManager = new ParameterXmlManager();
	
	
	public Element getElementFromItem(Method method, Document document) {
		Element methodElement = document.createElement("method");
		methodElement.setAttribute("name", method.getName().toString());
		methodElement.setAttribute("visibility", method.getVisibility() != null ? method.getVisibility().getType() : Visibility.PUBLIC.getType());
		methodElement.appendChild(typeManager.getElementFromItem(method.getReturnType(),
				document));
		Element modifiers = document.createElement("modifiers");
		for (Modifier modifier : method.getModifiers()) {
			modifiers.appendChild(modifierManager.getElementFromItem(modifier, document));
		}
		methodElement.appendChild(modifiers);
		Element parameters = document.createElement("parameters");
		for (Parameter parameter : method.getParameters()) {
			parameters.appendChild(parameterManager .getElementFromItem(parameter, document));
		}
		methodElement.appendChild(parameters);
		return methodElement;
	}

	@Override
	public Method getItemFromXmlElement(Element element) throws Exception {
		Method method = new Method();
		method.setVisibility(getVisibility(element.getAttribute("visibility")));
		method.setName(element.getAttribute("name"));
		method.setReturnType(typeManager.getItemFromXmlElement(
				(Element)element.getElementsByTagName("type").item(0)
			)
		);
		NodeList modifiersElem = element.getElementsByTagName("modifiers");
		NodeList modifiers = modifiersElem.item(0) != null ? modifiersElem.item(0).getChildNodes() : null;
    		if (modifiers != null) for (int i = 0; i < modifiers.getLength(); i++) {
    			Node node = modifiers.item(i);
    			if (node == null || !(node instanceof Element))
    				continue;
    			method.addModifier(modifierManager.getItemFromXmlElement((Element) node));
    		}
		NodeList parametersElem = element.getElementsByTagName("parameters");
		NodeList parameters = parametersElem.item(0) != null ? parametersElem.item(0).getChildNodes() : null;
		if (parameters != null) for (int i = 0; i < parameters.getLength(); i++) {
			Node node = parameters.item(i);
			if (node == null || !(node instanceof Element))
				continue;
			method.addParameter(parameterManager.getItemFromXmlElement((Element) node));
		}
		return method;
	}

	private Visibility getVisibility(String visibility) {
		if (Visibility.PUBLIC.getType().equals(visibility))
			return Visibility.PUBLIC;
		if (Visibility.PRIVATE.getType().equals(visibility))
			return Visibility.PRIVATE;
		if (Visibility.PROTECTED.getType().equals(visibility))
			return Visibility.PROTECTED;
		return Visibility.PUBLIC;
	}
}
